import { Context, Next } from 'koa';
import { CustomEnhance, Route } from './types';
import Router from 'koa-router';
import path from 'path';
import fs from 'fs';
import requireDir from 'require-dir';
import Result from './util/result';

const mapValue = (object) => object.default;

export const collectRoutes = () => {
    const routes = fs.existsSync(path.resolve(__dirname, './route')) ? requireDir(path.resolve(__dirname, './route'), { mapValue }) : {};
    const controllers = fs.existsSync(path.resolve(__dirname, './controller')) ? requireDir(path.resolve(__dirname, './controller'), { mapValue }) : {};
    const service = fs.existsSync(path.resolve(__dirname, './service')) ? requireDir(path.resolve(__dirname, "./service"), { mapValue }) : {};
    const model = fs.existsSync(path.resolve(__dirname, './model')) ? requireDir(path.resolve(__dirname, "./model"), { mapValue }) : {};

    const router = new Router();
    Object.entries(routes).forEach(([name, customRoutes]: [string, any]) => {
        const app = { controller: controllers, service, model };
        for (let { path, method = 'get', controller, guard } of customRoutes(app)) {
            router[method.toLowerCase()](path, async (ctx: Context, next: Next) => {
                const enhance: CustomEnhance = Object.assign(app, next);
                let result = await controller(ctx, enhance);
                ctx.body = Result.of(result);
            })
        }
    })
    return router.routes();
}